import {useEffect, useMemo, useState} from "react";
import useLatest from "./useLatest";

const calcLeft = t => {
  if (!t) {
    return 0
  }
  const left = new Date(t).getTime() - new Date().getTime()
  if (left < 0) {
    return 0
  }
  return left
}

const parseMs = milliseconds => ({
  days: Math.floor(milliseconds / 86400000).toString().padStart(2, '0'),
  hours: (Math.floor(milliseconds / 3600000) % 24).toString().padStart(2, '0'),
  minutes: (Math.floor(milliseconds / 60000) % 60).toString().padStart(2, '0'),
  seconds: (Math.floor(milliseconds / 1000) % 60).toString().padStart(2, '0'),
  milliseconds: (Math.floor(milliseconds) % 1000).toString().padStart(2, '0'),
})

/**
 * use examples:
 * countdown: 毫秒
 const [countdown, {days, hours, minutes, seconds, milliseconds}] = useCountdown({
    targetDate: new Date("2022-06-06 10:10:10"),
    interval: 1000,
    onEnd: () => {
      console.log("countdown is over")
    }
 })
 * */
export default function useCountdown(options) {
  const {targetDate, interval = 1000, onEnd} = options || {}
  const [timeLeft, setTimeLeft] = useState(() => calcLeft(targetDate))

  const onEndRef = useLatest(onEnd)

  useEffect(
    () => {
      if (!targetDate) {
        // stop
        setTimeLeft(0)
        return
      }

      // 立即执行一次
      setTimeLeft(calcLeft(targetDate))

      const timer = setInterval(() => {
        const targetLeft = calcLeft(targetDate)
        setTimeLeft(targetLeft)
        if (targetLeft === 0) {
          clearInterval(timer)
          onEndRef.current && onEndRef.current()
        }
      }, interval)

      // eslint-disable-next-line consistent-return
      return () => clearInterval(timer)
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [targetDate, interval]
  )

  const formattedRes = useMemo(() => parseMs(timeLeft), [timeLeft])
  const {days, hours, minutes, seconds} = formattedRes
  const formattedStr = `${days}D ${hours}:${minutes}:${seconds}`
  return [timeLeft, formattedRes, formattedStr]
}
